<!DOCTYPE html>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="resources/wasm-module-builder.js"></script>
<script>

const test = async_test("TestWasmWorkerTerminationWhileCompiling");

const kNumWorkers = 8;
const kNumFunctions = 5000;

// This function is executed by each worker.
function workerFunction() {
  onmessage = function(event) {
    // Start asynchronous compilation, then notify the main thread about that.
    WebAssembly.compile(event.data)
        .catch(e => postMessage("compilation error: " + e));
    postMessage("compiling");
  };
}

// Build a wasm module with a number of function, such that the workers need
// some time compiling it.
const builder = new WasmModuleBuilder();
for (var i = 0; i < kNumFunctions; ++i) {
  builder.addFunction('func' + i, kSig_v_v).addBody([kExprCallFunction, 0]);
}
const module_bytes = builder.toBuffer();

const blobURL =
    URL.createObjectURL(new Blob(['(' + workerFunction.toString() + ')()']));

// Counter to wait for all workers to start compilation.
var outstanding_worker_events = kNumWorkers;
const workers = [];

function workerEvent(event) {
  // If the event data is not "compiling", this is an error in the worker.
  assert_equals(event.data, "compiling");
  // Decrement counter of workers that did not start compiling yet.
  // Do nothing if there are still outstanding workers.
  assert_greater_than(outstanding_worker_events, 0);
  if (--outstanding_worker_events > 0) return;
  // All workers started compiling! Now terminate them all. This should not
  // crash.
  for (let i = 0; i < kNumWorkers; ++i) {
    workers[i].terminate();
  }
  test.done();
}

for (let i = 0; i < kNumWorkers; ++i) {
  const worker = new Worker(blobURL);
  worker.onmessage = test.step_func(workerEvent);
  worker.postMessage(module_bytes);
  workers.push(worker);
}

</script>
